home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_022 / pemacs / search.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  7KB  |  316 lines

  1. /*
  2.  * The functions in this file implement commands that search in the forward
  3.  * and backward directions. There are no special characters in the search
  4.  * strings. Probably should have a regular expression search, or something
  5.  * like that.
  6.  *
  7.  * REVISION HISTORY:
  8.  *
  9.  * ?    Steve Wilhite, 1-Dec-85
  10.  *      - massive cleanup on code.
  11.  *
  12.  *    Andy Poggio, 1 Apr 86 - added query replace
  13.  */
  14.  
  15. #include        <stdio.h>
  16. #include        "ed.h"
  17.  
  18. /*
  19.  * Query replace.  Replace pattern with new one at user's discretion.
  20.  * Bound to META-%.
  21.  */
  22. qreplace(f, n)
  23.     {
  24.     register int s;
  25.     short olen, repall;
  26.     char newpat[ NPAT];
  27.  
  28.     if ((s = readpattern("Replace old string", 0)) != TRUE)
  29.         return (s);
  30.     olen = strlen( pat);
  31.     if((s = mlreply( "with new string: ", newpat, sizeof newpat)) == ABORT)
  32.     return( s);
  33.  
  34.     repall = FALSE;
  35.     while( search()) {
  36.  
  37.     if( repall) s = TRUE;
  38.     else {
  39.       mlwrite("Replace?");
  40.       update();
  41. askuser:
  42.       switch( (*term.t_getchar)()) {
  43.  
  44.         case '\0177':
  45.         case '':
  46.         case 'n':
  47.         s = FALSE; /* don't replace */
  48.         break;
  49.  
  50.         case 'a':
  51.         repall = TRUE;
  52.         case ' ':
  53.         case 'y':
  54.         s = TRUE; /* replace */
  55.         break;
  56.  
  57.         case '\007':
  58.         s = ABORT;
  59.         break;
  60.  
  61.         default:
  62.         mlwrite(
  63.     "y or <SP>: replace;  n or <DEL>: don't;  a: all;  <^G>: abort");
  64.         update();
  65.         goto askuser;
  66.         break;
  67.       }
  68.     }
  69.  
  70.     if( s == TRUE) {
  71.         backdel( TRUE, olen); /* delete old string */
  72.         s = linsertstr( newpat);  /* and insert the new */
  73.     }
  74.     if( s == ABORT)
  75.         break;    
  76.     }
  77.     mlwrite("");
  78.     return( s);
  79. }
  80.  
  81. /*
  82.  * Search forward. Get a search string from the user, and search, beginning at
  83.  * ".", for the string. If found, reset the "." to be just after the match
  84.  * string, and [perhaps] repaint the display. Bound to "C-S".
  85.  */
  86. forwsearch(f, n)
  87.     {
  88.     register int s;
  89.  
  90.     if ((s = readpattern("Search", 0)) != TRUE)
  91.         return (s);
  92.  
  93.     s = search();
  94.     if( ! s) mlwrite("Not found");
  95.     return( s);
  96. }
  97.  
  98. search()
  99. {
  100.     register LINE *clp;
  101.     register int cbo;
  102.     register LINE *tlp;
  103.     register int tbo;
  104.     register int c;
  105.     register char *pp;
  106.  
  107.     clp = curwp->w_dotp;
  108.     cbo = curwp->w_doto;
  109.  
  110.     while (clp != curbp->b_linep)
  111.         {
  112.         if (cbo == llength(clp))
  113.             {
  114.             clp = lforw(clp);
  115.             cbo = 0;
  116.             c = '\n';
  117.             }
  118.         else
  119.             c = lgetc(clp, cbo++);
  120.  
  121.         if (eq(c, pat[0]) != FALSE)
  122.             {
  123.             tlp = clp;
  124.             tbo = cbo;
  125.             pp  = &pat[1];
  126.  
  127.             while (*pp != 0)
  128.                 {
  129.                 if (tlp == curbp->b_linep)
  130.                     goto fail;
  131.  
  132.                 if (tbo == llength(tlp))
  133.                     {
  134.                     tlp = lforw(tlp);
  135.                     tbo = 0;
  136.                     c = '\n';
  137.                     }
  138.                 else
  139.                     c = lgetc(tlp, tbo++);
  140.  
  141.                 if (eq(c, *pp++) == FALSE)
  142.                     goto fail;
  143.                 }
  144.  
  145.             curwp->w_dotp  = tlp;
  146.             curwp->w_doto  = tbo;
  147.             curwp->w_flag |= WFMOVE;
  148.             return (TRUE);
  149.             }
  150. fail:;
  151.         }
  152.     return (FALSE);
  153.     }
  154.  
  155. /*
  156.  * Reverse search. Get a search string from the user, and search, starting at
  157.  * "." and proceeding toward the front of the buffer. If found "." is left
  158.  * pointing at the first character of the pattern [the last character that was
  159.  j matched]. Bound to "C-R".
  160.  */
  161. backsearch(f, n)
  162.     {
  163.     register LINE *clp;
  164.     register int cbo;
  165.     register LINE *tlp;
  166.     register int tbo;
  167.     register int c;
  168.     register char *epp;
  169.     register char *pp;
  170.     register int s;
  171.  
  172.     if ((s = readpattern("Reverse search", 0)) != TRUE)
  173.         return (s);
  174.  
  175.     for (epp = &pat[0]; epp[1] != 0; ++epp)
  176.         ;
  177.  
  178.     clp = curwp->w_dotp;
  179.     cbo = curwp->w_doto;
  180.  
  181.     for (;;)
  182.         {
  183.         if (cbo == 0)
  184.             {
  185.             clp = lback(clp);
  186.  
  187.             if (clp == curbp->b_linep)
  188.                 {
  189.                 mlwrite("Not found");
  190.                 return (FALSE);
  191.                 }
  192.  
  193.             cbo = llength(clp)+1;
  194.             }
  195.  
  196.         if (--cbo == llength(clp))
  197.             c = '\n';
  198.         else
  199.             c = lgetc(clp, cbo);
  200.  
  201.         if (eq(c, *epp) != FALSE)
  202.             {
  203.             tlp = clp;
  204.             tbo = cbo;
  205.             pp  = epp;
  206.  
  207.             while (pp != &pat[0])
  208.                 {
  209.                 if (tbo == 0)
  210.                     {
  211.                     tlp = lback(tlp);
  212.                     if (tlp == curbp->b_linep)
  213.                         goto fail;
  214.  
  215.                     tbo = llength(tlp)+1;
  216.                     }
  217.  
  218.                 if (--tbo == llength(tlp))
  219.                     c = '\n';
  220.                 else
  221.                     c = lgetc(tlp, tbo);
  222.  
  223.                 if (eq(c, *--pp) == FALSE)
  224.                     goto fail;
  225.                 }
  226.  
  227.             curwp->w_dotp  = tlp;
  228.             curwp->w_doto  = tbo;
  229.             curwp->w_flag |= WFMOVE;
  230.             return (TRUE);
  231.             }
  232. fail:;
  233.         }
  234.     }
  235.  
  236. /*
  237.  * Compare two characters. The "bc" comes from the buffer. It has it's case
  238.  * folded out. The "pc" is from the pattern.
  239.  */
  240. eq(bc, pc)
  241.     int bc;
  242.     int pc;
  243.     {
  244.     if (bc>='a' && bc<='z')
  245.         bc -= 0x20;
  246.  
  247.     if (pc>='a' && pc<='z')
  248.         pc -= 0x20;
  249.  
  250.     if (bc == pc)
  251.         return (TRUE);
  252.  
  253.     return (FALSE);
  254.     }
  255.  
  256. /*
  257.  * Read a pattern. If newpat == 0, do the following.
  258.  * Stash it in the external variable "pat". The "pat" is not
  259.  * updated if the user types in an empty line. If the user typed an empty line,
  260.  * and there is no old pattern, it is an error. Display the old pattern, in the
  261.  * style of Jeff Lomicka. There is some do-it-yourself control expansion.
  262.  * If netpat != 0, ignore the old pattern.
  263.  */
  264. readpattern(prompt, newpat)
  265.     char *prompt, *newpat;
  266.     {
  267.     register char *cp1;
  268.     register char *cp2;
  269.     register int c;
  270.     register int s;
  271.     char tpat[NPAT+20];
  272.  
  273.     cp1 = &tpat[0];                     /* Copy prompt */
  274.     cp2 = prompt;
  275.  
  276.     while ((c = *cp2++) != '\0')
  277.         *cp1++ = c;
  278.  
  279.     if ((newpat == 0) && (pat[0] != '\0'))        /* Old pattern */
  280.         {
  281.         *cp1++ = ' ';
  282.         *cp1++ = '[';
  283.         cp2 = &pat[0];
  284.  
  285.         while ((c = *cp2++) != 0)
  286.             {
  287.             if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */
  288.                 {
  289.                 if (c<0x20 || c==0x7F) {
  290.                     *cp1++ = '^';
  291.                     c ^= 0x40;
  292.                     }
  293.                 else if (c == '%')      /* Map "%" to */
  294.                     *cp1++ = c;         /* "%%". */
  295.  
  296.                 *cp1++ = c;
  297.                 }
  298.             }
  299.  
  300.         *cp1++ = ']';
  301.         }
  302.  
  303.     *cp1++ = ':';                       /* Finish prompt */
  304.     *cp1++ = ' ';
  305.     *cp1++ = '\0';
  306.     s = mlreply(tpat, newpat ? newpat : tpat, NPAT);      /* Read pattern */
  307.  
  308.     if (s == TRUE) {                     /* Specified */
  309.         if( newpat == 0) strcpy(pat, tpat);
  310.     } else if (s == FALSE && newpat == 0 && pat[0] != 0)/* CR, but old one */
  311.         s = TRUE;
  312.  
  313.     return (s);
  314.     }
  315.  
  316.